home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok02.lha / M2Code / M2ACode / M2ACode.doc < prev    next >
Encoding:
Text File  |  1993-08-16  |  9.0 KB  |  208 lines

  1. (*---------------------------------------------------------------------------
  2.    :Program.    M2ACode
  3.    :Author.     Fridtjof Björn Siebert (Amok)
  4.    :Address.    Nobileweg 67, D-7000 Stuttgart-40
  5.    :Phone.      (0)711/822509
  6.    :Shortcut.   [fbs]
  7.    :Version.    0.99
  8.    :Date.       27.03.88
  9.    :Copyright.  Intern
  10.    :Language.   Modula-II
  11.    :Translator. M2Amiga
  12.    :Imports.    none.
  13.    :Contents.   Maschinensprache->Modula Converter
  14.    :Bugs.       M2Amiga isn't able to convert some Types, such as LONGINT to
  15.    :Bugs.       WORD. REG() gives a LONGINT, so a WORD can't be a result.
  16. ---------------------------------------------------------------------------*)
  17.  
  18. =============================================================================
  19.                      =   =   =   M2ACode   =   =   =
  20.  
  21.                           © Copyright  1988 by
  22.                             Fridtjof Siebert
  23.                               Nobileweg 67
  24.                      D-7000 Stuttgart 40 (Stammheim)
  25.                            Tel: (0)711/822509
  26. =============================================================================
  27.  
  28. M2ACode ist für und mit dem Meier-Vogt-Modula-II-Compiler geschrieben. Es
  29. ermöglicht,  PC-relative Maschinenroutinen in Modulaprogramme einzubinden.
  30. Dies ist normalerweise nur über Libraries, oder bei kleinen Routinen durch
  31. direktes Berechnen des Maschinencodes möglich. Nun können mit einem
  32. Assembler (z.B. Profimat) geschriebene Assemblerprogramme leicht in Module
  33. umgewandelt werden.
  34.  
  35. Um PC-relative Maschinenroutinen zu schreiben, muß man lediglich im Assem-
  36. blermenü `PC-relativ' anwählen. Probleme gibt es nur, wenn man in eine ab-
  37. solute Addresse schreiben möchte. Dazu muß man sie in ein Addressregister
  38. laden und dann indirekt addressieren:
  39. LEA  Addresse,Ax
  40. MOVE yyyy,(Ax)
  41. Möchte man in mehrere nahe beieinanderliegende Addressen schreiben, kann
  42. man auch mit Offset addressieren.
  43.  
  44. M2ACode erzeugt aus Maschinensprachecode compilierbare Definitions- und
  45. Implementationmodule. Dabei wird der Code mit der von SYSTEM exportierten
  46. INLINE()-Funktion eingefügt.
  47.  
  48. Es ist möglich, Werte in beliebigen Registern zu übergeben und von dort
  49. zurückzuerhalten.
  50.  
  51. Mit M2ACode ist es nur möglich, maximal eine Maschinenspracheprozedur in
  52. ein Modul umzuwandeln. Doch kann man leicht mit einem guten Texteditor
  53. verschiedene Prozeduren in einem Modul zusammenzufassen.
  54.  
  55. Syntax von M2ACode:
  56.  
  57. M2ACode Src {-cRx:TYPE|vRx:TYPE|-sRx} [-rRx:TYPE] [-sall] [-d] [-e] [-p]
  58.  
  59. Die Parameter in den geschweiften Klammern können beliebig oft angegeben
  60. werden, die in eckigen Klammern sind optional. Die Reihenfolge der
  61. Parameter ist egal. Wird kein Parameter angegeben, wird eine Kurzbe-
  62. schreibung der Syntax ausgegeben.
  63.  
  64. Src  ist der Name des PC-relativ assemblierte Maschinencodes. Normal
  65.      assemblierter, ausführbarer Code kann nicht verwendet werden. Dies
  66.      dürfte allerdings nicht allzu schlimm sein, da PC-relativer normal-
  67.      erweise schneller ist als absoluter Code. Die Maschinenroutine muß im
  68.      aktuellen Directory stehen. Der erzeugte Modulname und Procedurename
  69.      wird aus diesem Namen erzeugt, indem ein eventuelles Suffix (.xxx)
  70.      abgeschnitten wird. Für den Namen des Definition- und
  71.      Implementationmoduls wird .def bzw. .mod angehängt.
  72.  
  73. Rx   ist ein 68000-Register. Es kann groß und klein geschrieben werden: D2,
  74.      a5, A2,  etc.
  75.  
  76. TYPE ist ein zum Typ ADDRESS kompatibler Modula-II-Typ. Beispiele sind
  77.      LONGCARD, INTEGER, POINTER, etc.
  78.  
  79. Die Parameter:
  80.  
  81. -c    teilt M2ACode mit, daß der Maschinenroutine ein konstanter Wert vom Typ
  82.       TYPE im Register Rx übergeben wird. Zur Übergabe wird der Wert in den
  83.       Typ ADDRESS umgewandelt.
  84.  
  85. -v    ist das Gegenstück zu -c für variable Parameter. Nach Beendigung der
  86.       Maschinenroutine wird der dann in Rx stehende Wert zurück in TYPE
  87.       umgewandelt und von der Procedure in die Übergebene Variable
  88.       geschrieben.
  89.  
  90. -r    wird für Routinen verwendet, die ein Ergebnis mit RETURN zurückgeben.
  91.       Der Inhalt von Rx wird nach der Maschinenroutine in TYPE umgewandelt
  92.       und mit RETURN an das aufrufende Modul übergeben.
  93.  
  94. -s    rettet das Register Rx. Damit ist es möglich, für Modula wichtige
  95.       Register auf den Stack zu retten. Die Maschinenroutine braucht sich
  96.       dann nicht um die Zwischenspeicherung der Register zu kümmern.
  97.       Wahrscheinlich können D0, D1, A0 und A1 frei verwendet werden. Die
  98.       anderen Register sollten sicherheitshalber gespeichert werden. Register
  99.       werden zuerst gerettet, bevor ihnen Parameter übergeben werden. Es ist
  100.       also z. B. möglich, die Addresse einer Library in A6 zu übergeben, wenn
  101.       man A6 mit -sA6 rettet. Gespeicherte Register werden nach der
  102.       Beendigung der Maschinenroutine wieder zurückgeladen. Achtung: -s
  103.       funktioniert zusammen mit -r nicht ! (sorry)
  104.  
  105. -sall ermöglicht es, alle Register, außer A7, ohne jedes einzeln hinzu-
  106.       schreiben, auf den Stack zu retten.
  107.  
  108. -d    löscht ein Nullwort am Ende des Maschinencodes, wenn es auf einer nicht
  109.       durch 4 teilbaren Addresse liegt. Dies ist nötig, da Profimat die Länge
  110.       des Maschinencodes immer auf Vielfache von 4 aufrundet. Das evt.
  111.       angefügte Wort (ein oder drei BYTE sollten es nicht sein !!!) ist eine
  112.       Null. Da 0000H dem Assemblerbefehl `ori.b #xx' entspricht, wird das
  113.       erste Wort des nächsten Befehls übersprungen. Das kann verheerende
  114.       Folgen haben. Es ist also empfehlenswert, wenn man sicher ist, daß
  115.       das letzte Wort des wirklichen Programmes keine 0 ist, -d anzugeben.
  116.       Ansonsten muß man das letzte Wort eventuell von Hand aus dem
  117.       erzeugten Implementation- module entfernen.
  118.  
  119. -e    fügt ein `(*$E-*)' in das Implementation-Module ein. Dadurch wird
  120.       beim Compilieren der normale Code zum Einsteigen und Verlassen einer
  121.       Procedure weggelassen. LINK und UNLNK fällt weg, wodurch keine
  122.       Variablen in der Procedure verwendet werden können. Am Ende der
  123.       Procedure steht kein RTS. Die Assemblerroutine muß also den RTS-Befehl
  124.       enthalten. Register mit -s nicht gespeichert und  mit -r nicht
  125.       zurückgegeben werden, da der Rücksprung in der Routine selbst steht.
  126.       Wird -p nicht angegeben darf die Routine kein RTS enthalten. Die
  127.       Routine muß dann so geschrieben sein, daß der PC nach ihrer Beendigung
  128.       hinter ihr steht.
  129.  
  130. -p    Erzeugt eine Prozedur, der die Parameter direkt in die Register
  131.       übergeben werden. Dadurch wird der Programmablauf schneller. Es ist
  132.       jedoch nicht möglich, Register, denen Werte übergeben werden, mit -s
  133.       auf den Stack zu retten, da die Register schon vor dem Eintritt in die
  134.       Prozedur beschrieben werden. Ich habe leider keine Ahnung, welche
  135.       Register wie von M2Amiga benutzt werden. Als ich ausprobiert habe,
  136.       Werte in Registern zu übergeben, und andere Register auf den Stack zu
  137.       retten erhielt ich einen gnadenlosen Absturz (Arts hat versagt). Wer
  138.       etwas über die verwendung der Register weiß schreibe mir!
  139.  
  140. Beispiel:
  141.  
  142. M2ACode Bsp. -vA0:ADDRESS -cD0:CARDINAL -vD3:INTEGER -rA3:LONGCARD
  143.  
  144. erzeugt folgendes Definitionmodul und speichert es als Beispiel.def:
  145.  
  146.   DEFINITION MODULE Beispiel;
  147.  
  148.   FROM SYSTEM IMPORT BYTE,WORD,ADDRESS,BITSET,LONGSET,FFP;
  149.  
  150.   (*------  Beispiel  ------*)
  151.  
  152.   PROCEDURE Beispiel(VAR a:ADDRESS;b:CARDINAL;VAR c:INTEGER):LONGCARD;
  153.  
  154.   END Beispiel.
  155.  
  156. Außerdem wird das Implementationmodul Beispiel.mod erzeugt:
  157.  
  158.   IMPLEMENTATION MODULE Beispiel;
  159.  
  160.   FROM SYSTEM IMPORT BYTE,WORD,ADDRESS,BITSET,LONGSET,FFP,INLINE,SETREG,REG;
  161.  
  162.   (*------  Beispiel  ------*)
  163.  
  164.   PROCEDURE Beispiel(VAR a:ADDRESS;b:CARDINAL;VAR c:INTEGER):LONGCARD;
  165.  
  166.   BEGIN
  167.  
  168.     SETREG( 8,ADDRESS(a));
  169.     SETREG( 0,ADDRESS(b));
  170.     SETREG( 3,ADDRESS(c));
  171.  
  172.     INLINE(0xxxxH,0yyyyH, ... ,0zzzzH);
  173.  
  174.     a := ADDRESS(REG( 8));
  175.     c := INTEGER(REG( 3));
  176.  
  177.     RETURN LONGCARD(REG(11));
  178.  
  179.   END Beispiel;
  180.  
  181.   BEGIN
  182.   END Beispiel.
  183.  
  184. Der mit INLINE Eingefügte Code in der Mitte hängt von dem File `Beispiel'
  185. ab, das den Maschinencode enthält.
  186.  
  187. Die Module können jetzt compiliert und in Modulaprogramme eingebunden
  188. werden.
  189.  
  190. Im Directory M2ACodeDemo befindet sich ein Beispiel für die Einbindung
  191. eines Maschinenprogramms. DrawLines.asm ist der Assemblerquelltext für
  192. DrawLines. DrawLines.def und DrawLines.mod wurden mit `M2ACode
  193. DrawLines.prg -ca2:ADDRESS -ca6:ADDRESS -sd2 -sd3 -sa6 -d' erzeugt.
  194. Draw.mod ist der Modula-Quellcode für das Hauptprogramm. Es öffnet einen
  195. Screen und die Graphicslibrary. Der DrawMode wird auf Complement gesetzt.
  196. Danach wird DrawLines aufgerufen, was 20480 Linien zeichnet. Zum Schluß
  197. schließt Draw den Screen und die Graphics- library wieder.
  198.  
  199. Ein Demo, das sehr schön den Geschwindigkeitsunterschied zwischen Modula
  200. und Assembler zeigt, ist im M2ACodeDemo2-Directory. Sort.mod enthält eine
  201. einfache Sortierroutine für ein CardinalFeld. AssSort.asm ist die gleiche
  202. Routine in Assembler. Aus AssSort.prg wurden die AssSort.def und
  203. AssSort.mod-Files mit `M2ACode AssSort.prg -ca0:ADDRESS -cD0:LONGCARD -sd2
  204. -sd3 -sd4 -d -p' erstellt. Die Programme AssSortDemo und SortDemo füllen
  205. ein Feld mit 1000 zufälligen CARDINALs. Das Feld wird danach mit AssSort
  206. bzw. SortDemo sortiert und danach ausgegeben. Die Maschinenroutine ist
  207. fast 6x schneller als die in Modula.
  208.